/**
 * 单向循环链表,clist.c
 */
#include <stdlib.h>
#include <string.h>

#include "clist.h"

void clist_init(CList *list, void (*destroy)(void *data))
{
	list->size = 0;
	list->destroy = destroy;
	list->head = NULL;
}

void clist_destroy(CList *list)
{
	void *data;

	while (clist_size(list) > 0) {
		if (clist_rem_next(list, list->head, (void **)&data) == 0
			&& list->destroy != NULL) {
			list->destroy(data);
		}
	}

	memset(list, 0, sizeof(CList));
}

/**
 * 插入元素到链表list的节点element后面。
 * @param  list    链表
 * @param  element 节点
 * @param  data    数据
 * @return         成功返回0，失败-1
 */
int clist_ins_next(CList *list, CListElmt *element, const void *data)
{
	CListElmt *new_element;

	if ((new_element = (CListElmt *)malloc(sizeof(CListElmt))) == NULL)
		return -1;

	new_element->data = (void *)data;
	if (clist_size(list) == 0) {
		new_element->next = new_element;
		list->head = new_element;
	} else {
		new_element->next = element->next;
		element->next = new_element;
	}

	list->size++;
	return 0;
}

/**
 * 从链表list中删除element节点。
 * @param  list    链表
 * @param  element 节点
 * @param  data    被删除节点中的数据
 * @return         成功返回0，失败返回-1
 */
int clist_rem_next(CList *list, CListElmt *element, void **data)
{
	CListElmt *old_element;

	if (clist_size(list) == 0)
		return -1;

	*data = element->next->data;
	if (element->next == element) {
		old_element = element->next;
		list->head = NULL;
	} else {
		old_element = element->next;
		element->next = element->next->next;
		if (old_element == clist_head(list))
			list->head = old_element->next;
	}

	free(old_element);
	list->size--;
	
	return 0;
}
